home *** CD-ROM | disk | FTP | other *** search
- *--------------------------------------------------------------------------
-
- * MenuStay V1.0
-
-
- ; is FreeWare
-
- ; With this small tool it's now possible to go around the menus
- ; without holding the right mouse button.
- ; Just press AND release the right mouse button over the wished menubar.
-
- ; In the menu-stay-mode it's possible
- ; to add a command to items that don't have one,
- ; by pressing the left mouse button.
-
- ; To activate the screen blanker
- ; just press and release the cursor up and down keys simultaneous.
-
-
- ; Once installed, this tool only uses 568 bytes of memory.
- ; To get back to normal simply run the program again.
-
- ; No need to 'RUN' or 'RUNBACK' this tool from the CLI.
-
- ; 1993 by Alexandros Loghis
-
- * Sun Apr 18 21:25:19 1993
-
- ;:-)
-
-
- * Some information about this source code
-
- ; All routines where taken from
- ; Preben Nielsen's RMBShift V1.0 assembly source (thanks),
- ; exept the input handler that was written by myself.
-
- ; The whole program was (re)written in
- ; Joe Siebenmann's EZAsm V1.6 (Fish 592).
- ; Assembled with Charlie Gibbs A68k V2.71.
-
- ; EZAsm combines parts of "C" with 68000 assembly, giving it the "feel"
- ; of a higher level language.
- ; The resulting code is optimized as much as possible.
-
- *--------------------------------------------------------------------------
-
- include "exec/io.i"
- include "exec/memory.i"
- include "exec/interrupts.i"
- include "devices/input.i"
- include "devices/inputevent.i"
- include "libraries/dosextens.i"
-
- include "hardware/custom.i"
- include "hardware/dmabits.i"
- include "intuition/intuitionbase.i"
- include "intuition/intuition.i"
-
- *--------------------------------------------------------------------------
-
- LONG _DosBase WBMsg PProcess HMem
-
- *--------------------------------------------------------------------------
-
- Main PProcess = FindTask( 0 )
- a2 = d0
- pr_CLI(a2) = 0 l {
- WaitPort( &pr_MsgPort(a2) ) ;WBStart
- WBMsg = GetMsg( &pr_MsgPort(a2) )
- }
-
- _DosBase = OldOpenLibrary( &DosName(pc) )
- beq.s Error
- lea IntBase(pc),a2
- (a2) = OldOpenLibrary( &IntName(pc) )
- beq.s Error
-
- lea IHSName(pc),a1
- bsr FindThisPort
- beq.s DoInstall
-
- DoRemove
- CloseLibrary( IntBase(pc) )
- moveq #REMOVED,d7 because of the forward reference
- lea IHS(pc),a0
- lea PSEndIHS1(pc),a1
- lea PSEndIHS2(pc),a2
- bsr RemoveHandler
- beq.s ShowMsg
- moveq #CANTREMOVE,d7
- bra.s ShowMsg
-
- DoInstall
- moveq #INSTALLED,d7
- lea IHS(pc),a0
- lea PSPrepIHS1(pc),a1
- lea PSPrepIHS2(pc),a2
- bsr InstallHandler
- beq.s ShowMsg
- moveq #CANTINSTALL,d7
- ShowMsg d0 = d7 l
- bsr.s CONMsg
-
- Error _DosBase != 0 {
- CloseLibrary( _DosBase )
- }
-
- WBMsg != 0 {
- Forbid( )
- ReplyMsg( WBMsg )
- }
-
- END
-
- *--------------------------------------------------------------------------
-
- * Console message routines
-
- ;Writes a general copyright message and then a more specific message.
- ;Writes to standard output when run from CLI, and opens its own window
- ;when run from Workbench.
- ; >= D0 = Msg-number
-
- FHandle equr d5
-
- CONMsg movem.l d0-d7/a0-a6,-(sp)
- d4 = d0
- d6 = 0
- FHandle = Output( )
- bne.s 1$
- d6 = 1
- lea CONName(pc),a0
- FHandle = Open( a0 #MODE_OLDFILE )
- beq.s exit
- 1$ moveq #INFOMSG,d0
- bsr.s SendMsg
- d0 = d4
- bsr.s SendMsg
- d6 != 0 {
- Delay( 127 )
- Close( FHandle )
- }
- exit movem.l (sp)+,d0-d7/a0-a6
- rts
-
- *-------------
-
- ; >= d0 = Msg-number
-
- SendMsg neg.l d0
- d0 << 1
- lea CONMsgTable(pc),a0
- a0 += 0(a0,d0.l) w
- d2 = a0
- d3 = -1
- 1$ d3 ++
- (a0)+ != 0 b
- bne.s 1$
- Write( FHandle * * )
- rts
-
- INFOMSG = 0
- INSTALLED = -1
- REMOVED = -2
- CANTINSTALL = -3
- CANTREMOVE = -4
-
- CONText MACRO
- dc.w \1-CONMsgTable
- ENDM
- CONMsgTable CONText Msg
- CONText Msg1
- CONText Msg2
- CONText Msg3
- CONText Msg4
-
- CONName dc.b 'CON:100/60/330/63/MenuStay',0
- Msg dc.b 10,$9B,'0;33m MenuStay V1.0 '
- dc.b $9B,'0;31mis FreeWare',10
- dc.b ' 1993 by ',$9B,'0;33mAlexandros Loghis'
- dc.b $9B,'0;31m',10,' ',0
- Msg1 dc.b 'has now been installed...',10,0
- Msg2 dc.b 'has now been removed...',10,0
- Msg3 dc.b "Error: Can't install handler",10,0
- Msg4 dc.b "Error: Can't remove handler",10,0
- even
-
- *--------------------------------------------------------------------------
-
- * Inputhandler removal and installation routines
-
- ; This is general-purpose inputhandler removal-routine
- ; It only needs an ihs with a port-name to remove the handler
-
- ; >= a0 = ihs
- ; >= a1 = first ihs-installation-routine or NULL
- ; >= a2 = second ihs-installation-routine or NULL
- ; => d0 = 0 means succes
-
- rtsValue equr d7
-
- RemoveHandler
- movem.l d1/rtsValue/a0-a3/a6,-(sp)
- moveq #-1,rtsValue weil EZAsm über d7 opt. will
- a3 = a2
- a2 = a0
- d1 = a1
- beq.s 1$
- jsr (a1) ; a0 = ihs
- beq.s 2$
- a2 = d0
- 1$ a0 = a2
- d0 = #IND_REMHANDLER
- bsr.s TellInputDevice
- rtsValue = d0
- bne.s 2$
- RemPort( &ihs_Port(A2) )
- d0 = 0
- bra.s 3$
- 2$ d0 = -1
- 3$ d1 = a3
- beq.s 4$
- a0 = a2
- jsr (a3) ; a0 = ihs, d0 = 0 means succes
- 4$ d0 = rtsValue
- movem.l (sp)+,d1/rtsValue/a0-a3/a6
- rts
-
- *-------------
-
- ; This is general-purpose inputhandler installation-routine
- ; It only needs an ihs with a port-name to install the handler
-
- ; >= a0 = ihs
- ; >= a1 = first ihs-installation-routine or NULL
- ; >= a2 = second ihs-installation-routine or NULL
- ; => d0 = 0 means succes
-
- InstallHandler
- movem.l d1/rtsValue/a0-a3/a6,-(sp)
- moveq #-1,rtsValue else EZAsm will optimize using d7
- a3 = a2
- a2 = a0
- d1 = a1
- beq.s 1$
- jsr (a1) ; a0 = ihs
- beq.s 2$
- a2 = d0
- 1$ a0 = a2
- d0 = #IND_ADDHANDLER
- bsr.s TellInputDevice
- rtsValue = d0 l
- bne.s 2$
- lea ihs_Port(a2),a1
- MP+LN_NAME(A1) = ihs_PortName(A2) l ;MsgPort->mp_Node.ln_Name=Name
- MP+LN_PRI(A1) = 0 b ;MsgPort->mp_Node.ln_Pri = 0
- MP+LN_TYPE(A1) = #NT_MSGPORT b ;MsgPort->mp_Node.ln_Type=NT_MSGPORT
- MP_FLAGS(A1) = #PA_IGNORE b ;MsgPort->mp_Flags = PA_IGNORE
- AddPort( * )
- d0 = 0
- bra.s 3$
- 2$ d0 = -1
- 3$ d1 = a3
- beq.s 4$
- a0 = a2
- jsr (a3) ; a0 = ihs, d0 = 0 means succes
- 4$ d0 = rtsValue
- movem.l (sp)+,D1/rtsValue/A0-A3/A6
- rts
-
- *-------------
-
- ; Open the input device. Set up the I/O block to add or remove the
- ; input handler, and send the request to the input device. Finally,
- ; close the device
-
- ; >= a0 = ihs
- ; >= d0 = Function to perform (IND_ADDHANDLER/IND_REMHANDLER)
- ; => d0 = 0 means succes
-
- Size = IOSTD_SIZE+MP_SIZE
- IReq = -IOSTD_SIZE
- IPort = -MP_SIZE-IOSTD_SIZE
-
- TellInputDevice
- link a5,#-Size until unlk use of EZAsm variables not allowed
- movem.l d0/a5,-(sp)
- d0 = #Size-1 w
- 1$ -(a5) = 0 b
- dbra d0,1$
- movem.l (sp)+,d0/a5
-
- movem.l d1-d2/rtsValue/a0-a3/a6,-(sp)
- moveq #-1,rtsValue else EZAsm will optimize using d7
- d2 = d0
- a2 = a0
- lea IPort(a5),a3
- MP+LN_TYPE(a3) = #NT_MSGPORT b ; mp_Node.ln_Type=NT_MSGPORT;
- MP_FLAGS(a3) = #PA_SIGNAL b ; mp_Flags =PA_SIGNAL;
- AllocSignal( -1 )
- MP_SIGBIT(a3) = d0 b ; mp_SigBit =MPSigBit;
- bmi.s exit2
- FindTask( 0 )
- MP_SIGTASK(a3) = d0 l ; mp_SigTask =FindTask(0);
- lea MP_MSGLIST(a3),a0
- NEWLIST a0
- lea IReq(a5),a1
- ; ExtReq->io_Message.mn_ReplyPort=taskReplyPort;
- IO+MN_REPLYPORT(a1) = a3 l
- ; ExtReq->io_Message.mn_Node.ln_Type=NT_MESSAGE;
- IO+MN+LN_TYPE(a1) = #NT_MESSAGE b
- OpenDevice( &InputName(pc) 0 * 0 )
- D0 = 0 w { ; flag: error if > 0
- lea IReq(a5),a1
- IO_COMMAND(a1) = d2 w
- lea ihs_Interrupt(a2),a0
- IO_DATA(a1) = a0 l
- rtsValue = DoIO( * )
- CloseDevice( &IReq(a5) )
- }
- d0 = MP_SIGBIT(a3) b
- FreeSignal( * )
- exit2 d0 = rtsValue
- movem.l (sp)+,d1-d2/rtsValue/a0-a3/a6
- unlk a5
- rts
-
- *-------------
-
- ; Each handler should have such a pair of installation-routines.
- ; The first one is passed to InstallHandler in A1, and it
- ; is called immediately when entering InstallHandler.
- ; The second one is passed to InstallHandler in A2, and it
- ; is called if installation of handler and message-port succeeds.
-
- ; >= a0 = ihs
- ; => d0 has to point to ihs to be used when installation proceeds.
- ; If d0 = 0 then installation is aborted.
-
- PSPrepIHS1
- movem.l d1/a0-a1/a6,-(sp)
- HMem = AllocMem( #HandlerSize #MEMF_PUBLIC|MEMF_CLEAR )
- beq.s 2$
- a1 = d0
- lea IHS(pc),a0
- d0 = #HandlerSize
- movem.l d0/a0-a1,-(sp)
- CopyMem( * * * )
- movem.l (sp)+,d0/a0-a1
- ihs_Length(a1) = d0 l ; This will enable removal by other programs
- lea HandlerCode-IHS(a1),a0
- ihs_Interrupt+IS_CODE(a1) = a0 ; ihs_Interrupt.is_Code = Handler
- ihs_Interrupt+IS_DATA(a1) = 0 l ; ihs_Interrupt.is_Data = 0
- lea IHSName-IHS(a1),a0
- ihs_PortName(A1) = a0 l ; ihs_PortName = IHSName
- ; ihs_Interrupt.is_Node.ln_Pri = HPRI
- ihs_Interrupt+LN_PRI(a1) = #HPRI b
- d0 = a1
- 2$ movem.l (sp)+,d1/a0-a1/a6
- rts
-
- *-------------
-
- ; >= a0 = ihs
- ; => d0 = 0 means everything went perfect
- ; -1 means something went wrong during installation
-
- PSPrepIHS2
- movem.l d0-d1/a0-a1/a6,-(sp)
- d0 != 0 {
- d0 != HMem {
- FreeMem( d0 #HandlerSize )
- }
- }
- movem.l (sp)+,d0-d1/a0-a1/a6
- rts
-
- *-------------
-
- ; Each handler should have such a pair of ending-routines.
- ; The first one is passed to RemoveHandler in A1, and it
- ; is called immediately when entering RemoveHandler.
- ; The second one is passed to RemoveHandler in A2, and it
- ; is called if removal of handler and message-port succeeds.
-
- ; >= a0 = ihs
- ; => d0 has to point to ihs to be used when removal proceeds
- ; If D0 = 0 then removal is aborted
-
- PSEndIHS1
- -(sp) = a1
- lea IHSName(pc),a1
- bsr.s FindThisPort
- a1 = (sp)+
- rts
-
- *-------------
-
- ; >= a0 = ihs
- ; => d0 = 0 means everything went perfect
- ; -1 means something went wrong during removal
-
- PSEndIHS2
- movem.l d0-d1/a0-a1/a6,-(sp)
- d0 >= 0 {
- FreeMem( a0 ihs_Length(a0) )
- }
- movem.l (sp)+,d0-d1/a0-a1/a6
- rts
-
- *-------------
-
- ; >= a1 = Portname
- ; => d0 = Port or NULL (cc reflects result also)
-
- FindThisPort
- movem.l d1-d2/a0-a1/a6,-(sp)
- d2 = a1
- Forbid( )
- d2 = FindPort( d2 )
- Permit( )
- d0 = d2
- movem.l (sp)+,d1-d2/a0-a1/a6
- rts
-
-
- *--------------------------------------------------------------------------
-
- * Input-handler start
-
- ihs_Port = 0
- ihs_Interrupt = MP_SIZE
- ihs_ID = MP_SIZE+IS_SIZE
- ihs_Length = MP_SIZE+IS_SIZE+4
- ihs_Flags = MP_SIZE+IS_SIZE+8
- ihs_PortName = MP_SIZE+IS_SIZE+10
- ihs_LocalArea = MP_SIZE+IS_SIZE+14
- ihs_SIZE = MP_SIZE+IS_SIZE+14
-
- ihs_Start MACRO
- dcb.b MP_SIZE,0 ; Message-Port structure
- dcb.b IS_SIZE,0 ; Interrupt structure
- dc.l 'P_IH' ; ID
- dc.l 0 ; Length of handler
- dc.w 0 ; Flags
- dc.l 0
- ENDM
-
- HPRI = 55
- HDisabled = 0
- HNoExtRemoval = 1
-
- ; This is the handler-block
- IHS ihs_Start
-
- ; Put local data here
- IfBlanker dc.b 0 must be before IfRMBDown !
- IfRMBDown dc.b 0 must be after IfBlanker !
- IntBase dc.l 0
- RawKeyBuffer dcb.w 5,0 last 5 pressed keys
- RKBLastElem = *-2
-
- ; IHS name
- IHSName dc.b 'MenuStay V1.0 Port',0
- even
-
-
- ; For each event in the event list:
- ; If we were waiting for this event then signal the task.
- ; When all the events have been checked, return the event list so that
- ; others can do their things.
-
- Next = ie_NextEvent
- Class = ie_Class
- Code = ie_Code
- Qual = ie_Qualifier
-
- EList equr a0
- Event equr a1
-
- Tmp equr a2
- BPtr equr a3 Raw key buffer pointer
- WPtr equr a3 Active window pointer
- Dma equr a4
- IfB equr a5 Ptr to IfBlanker
- IfRD equr a5 IfRMBDown
-
- RegLst reg Event/EList/Tmp/BPtr/Dma/IfB/d1
-
- *-------------
-
- TstHPos tst.b vhposr-dmacon(Dma)
- bne.s TstHPos
- btst #0,vposr+1-dmacon(Dma)
- bne.s TstHPos
- rts
-
- *-------------
-
- * Change these constants to activate the blanker with an other key combination
-
- Key1Up equ $cc Raw key code from cursor up when released
- Key1Dn equ $4c " " pressed
- Key2Up equ $cd Raw key code from cursor down when released
- Key2Dn equ $4d " " pressed
-
- TstUp cmp.w #Key1Up,-(BPtr)
- beq.s 1$
- cmp.w #Key2Up,(BPtr)
- 1$ rts
- TstDwn subq.l #2,BPtr
- TstDwn2 cmp.w #Key1Dn,(BPtr)
- beq.s 1$
- cmp.w #Key2Dn,(BPtr)
- 1$ rts
-
- *-------------
-
- TstBlanker
- (IfB) != 0 {
- bsr.s TstHPos
- (Dma) = #DMAF_SETCLR|DMAF_COPPER|DMAF_RASTER w
- (IfB) -- b
- }
- rts
-
- *-------------
-
- ; >= a0 = List of InputEvents
- ; >= a1 = HandlerData
-
- HandlerCode
- movem.l RegLst,-(sp)
- Event = EList l
- ieLoop d0 = Event
- beq NoMoreEvents
-
- lea $dff000+dmacon,Dma
- lea IfBlanker(pc),IfB
-
- cmpi.b #IECLASS_RAWKEY,Class(Event)
- bne.s NxtTst
- bsr.s TstBlanker
- d0 = Code(Event) w
- cmp.w RKBLastElem(pc),d0 still pressing the same key ?
- beq.s NxtTst yes
- lea RawKeyBuffer(pc),BPtr prepare
- lea RawKeyBuffer+2(pc),Tmp to
- d0 = #(RKBLastElem-RawKeyBuffer-1)/2 ; shift
- 1$ (BPtr)+ = (Tmp)+ w ; the
- dbra d0,1$ ; RawKeyBuffer
- (BPtr)+ = Code(Event) w ; enter actual key
-
- bsr.s TstUp test if the 2 key where pressed
- bne.s NxtTst
- bsr.s TstUp
- beq.s 2$
- bsr.s TstDwn2
- bne.s NxtTst
- bsr.s TstUp and then if there where released
- bne.s NxtTst
- 2$ bsr.s TstDwn
- bne.s NxtTst
- bsr.s TstDwn
- bne.s NxtTst
-
- bsr TstHPos wait until start of raster
- (Dma) = #DMAF_COPPER|DMAF_RASTER w ; screen
- color-dmacon(Dma) = 0 w ; and
- spr+4-dmacon(Dma) = 0 l ; mouse blanking
- (IfB) ++ b ; set flag to true
- NxtTst
-
- cmpi.b #IECLASS_RAWMOUSE,Class(Event)
- bne.s NxtEv
- bsr.s TstBlanker
- IfRD ++ l ; IfB is from now tabu
- cmpi.w #IECODE_LBUTTON,Code(Event)
- beq.s PressLMB
- cmpi.w #IECODE_RBUTTON,Code(Event)
- beq.s PressRMB
- cmpi.w #IECODE_UP_PREFIX|IECODE_RBUTTON,Code(Event)
- bne.s NxtEv
- ReleaseRMB
- tst.b (IfRD)
- beq.s NxtEv
- bsr.s TstMenuBar
- bcs.s DontRemove
- bra.s clear
- PressRMB
- (IfRD) = 0 {
- bsr.s TstMenuBar
- bcc.s NxtEv
- (IfRD) ++ b
- bra.s NxtEv
- }
- clear (IfRD) = 0
- DontRemove
- (IfRD) != 0 {
- Class(Event) = 0 w ; Kill event (make it an IECLASS_NULL event)
- (IfRD) ++ b ; (IfRD) = 2 = staymode on
- }
- NxtEv Event = Next(Event) l ; Just move on to next Event
- bra ieLoop
-
- NoMoreEvents
- d0 = EList
- movem.l (sp)+,RegLst
- rts
-
- *-------------
-
- TstMenuBar
- Tmp = IntBase(pc) l
- WPtr = ib_ActiveWindow(Tmp) l
- wd_MenuStrip(WPtr) != 0 l { ; if exists
- Tmp = ib_ActiveScreen(Tmp) l
- d0 = sc_MouseY(Tmp) w
- d0 < #$100 w {
- d0 < sc_BarHeight(Tmp) b
- }
- }
- rts ; carry flag = 1 means MousePtr in menubar
-
- *-------------
-
- CHARNR equ 256 array length
-
- lft equr d0 left border
- rght equr d1 right "
-
- Mn equr a2
- Item equr a3
- HiIt equr a4 Highlighted item
- Base equr a5 Base address from array of ASCII codes
-
- PressLMB
- cmp.b #2,(IfRD) ; (IfRD) = 2 = staymode on
- bne.s NxtEv
-
- Base = sp l
- lea -CHARNR(sp),sp
- d0 = #(CHARNR/4)-1
- 1$ -(Base) = 0 l ; clear array
- dbra d0,1$ Base = sp
-
- Tmp = IntBase(pc) l
- Tmp = ib_ActiveWindow(Tmp) l
- Mn = wd_MenuStrip(Tmp) l
- sub.l HiIt,HiIt
-
- Menus d0 = mu_FirstItem(Mn) l
- beq.s noItems
- bsr.s RekSrch
- noItems Mn = mu_NextMenu(Mn) l
- d0 = Mn
- bne.s Menus
-
- d0 = HiIt ; any item highlighted ?
- beq.s exit3 no
- tst.b mi_Command(HiIt) command already exists ?
- bne.s exit3 yes
-
- moveq #'Z'-'A',rght = 25
- bigEQsm 'A'(Base,rght.w) != 0 b { ; big letters command = small
- 'a'(Base,rght.w) ++ b ; letters com.
- }
- 'A'(Base,rght.w) ++ b ; don't use big letters commands
- rght -- b
- bpl.s bigEQsm until negative
-
- moveq #'a',lft small
- moveq #'z',rght letters
- bsr.s ChrSrch
- beq.s found
-
- moveq #'0',lft numbers
- moveq #'9',rght
- bsr.s ChrSrch
- beq.s found
-
- moveq #'!',lft all printable
- moveq #'~',rght chars
- bsr.s ChrSrch
- bne.s exit3 not found
-
- found mi_Command(HiIt) = lft b ; set command
- or.w #COMMSEQ,mi_Flags(HiIt) set command flag
- Class(Event) = 0 w ; Kill event (make it an IECLASS_NULL event)
-
- exit3 lea CHARNR(sp),sp
- bra NxtEv
-
- *-------------
-
- RekSrch ; rekursive searching throught items
- Item = d0
- d0 = mi_Flags(Item) w
- d0 &= #HIGHITEM w ; Test if item currently highlighted
- beq.s 1$ no
- HiIt = Item l
- d0 = 0
- 1$ d0 = mi_Command(Item) b ; get char
- 0(Base,d0.w) ++ b ; mark it in the array
- d0 = mi_SubItem(Item)
- beq.s noSubIt
- -(sp) = Item l
- bsr.s RekSrch
- Item = (sp)+ l
- noSubIt d0 = mi_NextItem(Item)
- bne.s RekSrch
- rts
-
- *-------------
-
- ChrSrch ; search for the first unused char that is >= lft & <= rght
- 0(Base,lft.w) != 0 b {
- lft ++ b
- cmp.b rght,lft
- bls.s ChrSrch
- }
- rts ; zero flag = 1 then a char was found
-
- *-------------
-
- HandlerSize = *-IHS
-
- *--------------------------------------------------------------------------
-
- DosName dc.b "dos.library",0
- even
- InputName dc.b "input.device",0
- even
- IntName dc.b "intuition.library",0
- even
-